/**
 * 
 */
package baduga.client;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.UnknownHostException;








/** SSL libs*/
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

import baduga.core.Core_Exception;
import baduga.core.Core_JsonDataSchema;
import baduga.core.Core_Messages;
import baduga.core.Core_Network_Api;

/**
 * @author Janek
 *
 */
public class  Network_Api extends Core_Network_Api {

	/** Informacja czy klient jest połączony */
	private static boolean conected = false;
	
	/** Factor SSL */
	private static SSLSocketFactory factorySSL = null;
	
	/** Socket SSL dla klienta */
	private static SSLSocket clientSocketSSL;
	
	/** Auto Zamykanie połączenia */
	private static boolean autoClose = false;
	
	
	/** Bufory */
	private static BufferedReader 	inboundData;
	private static PrintWriter 		outboundData; 
	
	
	/** Client Thread */
	private Network_API__ClientThread clientThread = null;
	
	
	
	/** Tablica kodów błędów */
	
	
	
	public Network_Api()
	{
		setSSLProperties();
	}
	
	
	
	/**
	 * Funkcja ustala własności połączenia over SSL
	 */
	private final void setSSLProperties()
	{
    	this.passwords[0] = "#a023F9$a%+0_0)_";
    	this.passwords[1] = "QpW--@0S(Wc#a";

    	/**  Poprawa ściezki */
    	this.dataCerts[1] +="_cli.p12";
    	
    	/** debug SSL-a */
    	Network_Api.sslDebug = true;
    	
    	/** Ustawienia dla klienta */
		System.setProperty("javax.net.ssl.keyStoreType", 	"pkcs12");
		System.setProperty("javax.net.ssl.trustStoreType", 	"jks");
		System.setProperty("javax.net.ssl.keyStore", this.dataCerts[0] + this.dataCerts[1] );
		System.setProperty("javax.net.ssl.trustStore", this.dataCerts[0] + this.dataCerts[2]  );
		System.setProperty("javax.net.debug", "ssl");
		System.setProperty("javax.net.ssl.keyStorePassword", this.passwords[0]);
		System.setProperty("javax.net.ssl.trustStorePassword", this.passwords[1]);
		
		
		factorySSL = (SSLSocketFactory) SSLSocketFactory.getDefault();
	}
	
	
	
	/**
	 * Funkcja wykonuje połączenie z serwerem.
	 * Jeżeli się powiedzi zwraca sukces.
	 * 
	 * @param hostname
	 * @param port
	 * @return
	 */
	public void connect(String hostname, int port)
	{
		if(!conected)
		{

				try {
					clientSocketSSL = (SSLSocket) factorySSL.createSocket(hostname, port);
					conected  = true;
				} catch (UnknownHostException e1) {
					//TODO: DBG_IMPROVE_FUTURE
					Core_Exception.showOwnMessage(Core_Messages.getMessage(0x02FB), Core_Messages.getMessage(0x0100));
				} catch (IOException e) {
					//TODO: DBG_IMPROVE_FUTURE
					Core_Exception.showOwnMessage(Core_Messages.getMessage(0x02F6), Core_Messages.getMessage(0x0100));
				}

			
			
			if(conected)
			{
				//Inicjalizacja wątku
				clientThread = new Network_API__ClientThread(clientSocketSSL, conected);
				
				//W trybie demina
				clientThread.setDaemon(true);
				
				//Odpalenie
				clientThread.start();
			}
		}
	}
	
	
	/**
	 * Przekierowuje strukturę JSONA do wątku
	 * 
	 * @param data
	 */
	public boolean sendData(Core_JsonDataSchema data)
	{
		boolean opStatus = false;
		
		if(clientThread != null && conected)
		{
			opStatus = clientThread.sendData(data);
		}
		
		return opStatus;
	}
	
	
	
	
	
	
	
	/**
	 * Funkcja rozłącza połączenie z serwerem.
	 * Zwraca sukces jeśli nic po drodze się nie stało.
	 * 
	 * @return
	 */
	public boolean disconnect()
	{
		boolean opStatus;
		
		if(clientThread != null)
		{
			opStatus =  clientThread.disConnect();
			
			clientThread = null;
		}
		else
		{
			opStatus = false;
		}
		

		return opStatus;
		
	}
	
	
	
	
	/**
	 * Zwraca informację do klasy wywołującej czy połączenie istnieje.
	 * @return
	 */
	public static boolean isConnected()
	{
		return conected;
	}
	
}